package epidemic

import (
	"fmt"
	"gitee.com/baal1990/epidemic/global"
	response "gitee.com/baal1990/epidemic/model/common/response_dfitc"
	"gitee.com/baal1990/epidemic/model/epidemic"
	epidemicReq "gitee.com/baal1990/epidemic/model/epidemic/request"
	epidemicRsp "gitee.com/baal1990/epidemic/model/epidemic/response"
	"gitee.com/baal1990/epidemic/service"
	"gitee.com/baal1990/epidemic/utils/validator"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type EpidemicRelatedStaffApi struct {
}

var epidemicRelatedStaffService = service.ServiceGroupApp.EpidemicServiceGroup.EpidemicRelatedStaffService

// CreateEpidemicRelatedStaff 创建EpidemicRelatedStaff
// @Tags EpidemicRelatedStaff
// @Summary 创建EpidemicRelatedStaff
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body epidemic.EpidemicRelatedStaff true "创建EpidemicRelatedStaff"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /epidemicRelatedStaff/createEpidemicRelatedStaff [post]
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) CreateEpidemicRelatedStaff(c *gin.Context) {
	operaterUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var epidemicRelatedStaff epidemic.EpidemicRelatedStaff
	_ = c.ShouldBindJSON(&epidemicRelatedStaff)
	//非超级管理员编辑时候判断
	if operaterUser.Role != global.DICT_ROLES_SUPER {
		if operaterUser.Company != epidemicRelatedStaff.Company ||
			!validator.ValidateDepartment(operaterUser.Department, epidemicRelatedStaff.Department) {
			response.FailWithMessage("账号权限不足", c)
			return
		}
	}
	if err := epidemicRelatedStaffService.CreateEpidemicRelatedStaff(epidemicRelatedStaff); err != nil {
		global.GVA_LOG.Error("创建失败!", zap.Error(err))
		response.FailWithMessage("创建失败", c)
	} else {
		response.OkWithMessage("创建成功", c)
	}
}

// DeleteEpidemicRelatedStaff 删除EpidemicRelatedStaff
// @Tags EpidemicRelatedStaff
// @Summary 删除EpidemicRelatedStaff
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body epidemic.EpidemicRelatedStaff true "删除EpidemicRelatedStaff"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /epidemicRelatedStaff/deleteEpidemicRelatedStaff [delete]
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) DeleteEpidemicRelatedStaff(c *gin.Context) {
	id := c.Param("id")
	if id == "" {
		global.GVA_LOG.Error("参数错误!id 为 0!!!")
		response.FailWithMessage("参数错误", c)
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", id))
	if err := epidemicRelatedStaffService.DeleteEpidemicRelatedStaff(id); err != nil {
		global.GVA_LOG.Error("操作失败!", zap.Error(err))
		response.FailWithMessage("操作失败", c)
	} else {
		response.Ok(c)
	}
}

// FindEpidemicRelatedStaff 用id查询EpidemicRelatedStaff
// @Tags EpidemicRelatedStaff
// @Summary 用id查询EpidemicRelatedStaff
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query epidemic.EpidemicRelatedStaff true "用id查询EpidemicRelatedStaff"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /epidemicRelatedStaff/findEpidemicRelatedStaff [get]
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) FindEpidemicRelatedStaff(c *gin.Context) {
	var epidemicRelatedStaff epidemic.EpidemicRelatedStaff
	_ = c.ShouldBindQuery(&epidemicRelatedStaff)
	if reepidemicRelatedStaff, err := epidemicRelatedStaffService.GetEpidemicRelatedStaff(epidemicRelatedStaff.ID); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		response.OkWithData(gin.H{"reepidemicRelatedStaff": reepidemicRelatedStaff}, c)
	}
}

// GetEpidemicRelatedStaffList 分页获取EpidemicRelatedStaff列表
// @Tags EpidemicRelatedStaff
// @Summary 分页获取EpidemicRelatedStaff列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query epidemicReq.EpidemicRelatedStaffSearch true "分页获取EpidemicRelatedStaff列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /epidemicRelatedStaff/getEpidemicRelatedStaffList [get]
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) GetEpidemicRelatedStaffList(c *gin.Context) {
	epidemicUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var pageInfo epidemicReq.EpidemicRelatedStaffSearch
	_ = c.ShouldBindQuery(&pageInfo)
	// name 参数需要rsa解密
	if pageInfo.Name != "" {
		nameDecodeBytes, err := global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(pageInfo.Name)
		if err != nil {
			global.GVA_LOG.Error("解密失败", zap.Error(err))
			response.FailWithMessage("参数错误", c)
			return
		}
		pageInfo.Name = string(nameDecodeBytes)
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", pageInfo))
	if list, total, err := epidemicRelatedStaffService.GetEpidemicRelatedStaffInfoList(pageInfo, epidemicUser); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		// 获取今日填报率
		filling, err := epidemicRelatedStaffService.GetFillingProcess(epidemicUser, pageInfo.Name)
		if err != nil {
			global.GVA_LOG.Error("GetFillingProcess失败!", zap.Error(err))
			response.FailWithMessage("获取失败", c)
		}
		var process string
		if total == 0 {
			process = "1.00"
		} else {
			tmp := float32(filling) / float32(total)
			process = fmt.Sprintf("%.2f", tmp)
		}
		// 获取自动通知开启状态
		status, err := epidemicRelatedStaffService.GetAutoNotifyStatus(epidemicUser)
		if err != nil {
			global.GVA_LOG.Error("GetAutoNotifyStatus失败!", zap.Error(err))
			response.FailWithMessage("获取失败", c)
		}
		response.OkWithDetailed(response.PageResultStaff{
			List:     list,
			Total:    total,
			Process:  process,
			Status:   status,
			Page:     pageInfo.Page,
			PageSize: pageInfo.PageSize,
		}, "获取成功", c)
	}
}

// 用户侧
// 涉疫登记信息查询
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) GetEpidemicRelatedStaffInfoUserSide(c *gin.Context) {
	curUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	info, err := epidemicRelatedStaffService.GetEpidemicRelatedStaffInfoUserSide(curUser.Mobile)
	if err != nil {
		global.GVA_LOG.Error("操作失败!", zap.Error(err))
		response.FailWithMessage("操作失败", c)
	} else {
		result := epidemicRsp.EpidemicRelatedStaffInfoUserSide{
			Id:                    int(info.ID),
			Name:                  info.Name,
			Mobile:                info.Mobile,
			Company:               info.Company,
			Department:            info.Department,
			Organization:          info.Organization,
			Location:              info.Location,
			AppletReport:          info.AppletReport,
			IsolationType:         info.IsolationType,
			Region:                info.Region,
			ResidentialAddress:    info.ResidentialAddress,
			Community:             info.Community,
			CommunityTel:          info.CommunityTel,
			Street:                info.Street,
			Description:           info.Description,
			CommunityRequirements: info.CommunityRequirements,
		}
		if info.HomeBeginDate != nil {
			result.HomeBeginDate = info.HomeBeginDate.Format("2006-01-02")
		}
		// 处理加密字段
		result.Name, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(result.Name))
		if err != nil {
			global.GVA_LOG.Error("加密Name失败!", zap.Error(err))
			response.FailWithMessage("操作失败", c)
		}
		result.Mobile, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(result.Mobile))
		if err != nil {
			global.GVA_LOG.Error("加密Mobile失败!", zap.Error(err))
			response.FailWithMessage("操作失败", c)
		}
		result.Region, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(result.Region))
		if err != nil {
			global.GVA_LOG.Error("加密Region失败!", zap.Error(err))
			response.FailWithMessage("操作失败", c)
		}
		result.ResidentialAddress, err = global.AsymmetricCrypto.EncryptWithPrvKOutputBase64([]byte(result.ResidentialAddress))
		if err != nil {
			global.GVA_LOG.Error("加密ResidentialAddress失败!", zap.Error(err))
			response.FailWithMessage("操作失败", c)
		}
		response.OkWithData(result, c)
	}
}

// 用户侧
// 涉疫登记
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) EpidemicRelatedStaffCheckinUserSide(c *gin.Context) {
	curUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var req epidemicReq.EpidemicRelatedStaffCheckinUserSide
	if err := c.ShouldBind(&req); err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", req))
	// 处理加密字段
	req, err := relatedStaffDecodeUserSide(req)
	if err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	// 下列信息从当前登录用户中获取
	req.Name = curUser.Name
	req.Mobile = curUser.Mobile
	req.Company = curUser.Company
	req.Department = curUser.Department
	req.Organization = curUser.Organization
	if err := epidemicRelatedStaffService.EpidemicRelatedStaffCheckinUserSide(req); err != nil {
		global.GVA_LOG.Error("操作失败!", zap.Error(err))
		response.FailWithMessage("操作失败", c)
	} else {
		response.Ok(c)
	}
}

// 用户侧
// 健康登记
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) HealthCheckinUserSide(c *gin.Context) {
	curUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	var health epidemicReq.HealthCheckinUserSide
	if err := c.ShouldBind(&health); err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	health.Mobile = curUser.Mobile
	global.GVA_LOG.Info("请求参数", zap.Any("param", health))
	if err := epidemicRelatedStaffService.EpidemicRelatedStaffInfoUserSide(curUser.Mobile, curUser.Name, health); err != nil {
		global.GVA_LOG.Error("操作失败!", zap.Error(err))
		response.FailWithMessage("操作失败", c)
	} else {
		response.Ok(c)
	}
}

// 导出全部
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) ExportAll(c *gin.Context) {
	user := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	fileName, err := epidemicRelatedStaffService.ExportAll(user)
	if err != nil {
		global.GVA_LOG.Error("导出失败!", zap.Error(err))
		response.FailWithMessage("导出失败", c)
	} else {
		fileLinck := global.GVA_CONFIG.System.AccessHost + fileName
		response.OkWithData(fileLinck, c)
	}
}

// 编辑涉疫人员信息
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) SaveEpidemicRelatedStaff(c *gin.Context) {
	operationUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	info := epidemicReq.EpidemicRelatedStaffSet{}
	err := c.ShouldBind(&info)
	if err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", info))
	// 处理密文
	if info, err = relatedStaffDecode(info); err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	//非超级管理员编辑时候判断
	if operationUser.Role != global.DICT_ROLES_SUPER {
		if operationUser.Company != info.Company ||
			!validator.ValidateDepartment(operationUser.Department, info.Department) {
			response.FailWithMessage("账号权限不足", c)
			return
		}
	}
	if err := epidemicRelatedStaffService.SaveEpidemicRelatedStaff(operationUser.Name, info); err != nil {
		global.GVA_LOG.Error("操作失败!", zap.Error(err))
		response.FailWithMessage("操作失败", c)
	} else {
		response.Ok(c)
	}
}

// 处理涉疫信息中加密字段
func relatedStaffDecode(req epidemicReq.EpidemicRelatedStaffSet) (result epidemicReq.EpidemicRelatedStaffSet, err error) {
	result = req
	tmp := []byte{}
	// 解密姓名
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.Name); err != nil {
		return result, err
	}
	result.Name = string(tmp)
	// 解密手机号
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.Mobile); err != nil {
		return result, err
	}
	result.Mobile = string(tmp)
	// 解密行政编码
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.Region); err != nil {
		return result, err
	}
	result.Region = string(tmp)
	// 解密行政区
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.RegionName); err != nil {
		return result, err
	}
	result.RegionName = string(tmp)
	// 解密详细地址
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.ResidentialAddress); err != nil {
		return result, err
	}
	result.ResidentialAddress = string(tmp)
	return result, err
}

// 用户侧-处理涉疫信息中加密字段
func relatedStaffDecodeUserSide(req epidemicReq.EpidemicRelatedStaffCheckinUserSide) (result epidemicReq.EpidemicRelatedStaffCheckinUserSide, err error) {
	result = req
	var tmp []byte
	// 解密行政编码
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.Region); err != nil {
		return result, err
	}
	result.Region = string(tmp)
	// 解密行政区
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.RegionName); err != nil {
		return result, err
	}
	result.RegionName = string(tmp)
	// 解密详细地址
	if tmp, err = global.AsymmetricCrypto.DecryptWithPrvKeyFromBase64(req.ResidentialAddress); err != nil {
		return result, err
	}
	result.ResidentialAddress = string(tmp)
	return result, err
}

// AutoNotify 开启关闭通知
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) AutoNotify(c *gin.Context) {
	operationUser := c.MustGet("OPERATION_USER_INFO").(epidemic.EpidemicUser)
	if operationUser.Role != global.DICT_ROLES_SUPER {
		global.GVA_LOG.Error("权限不足")
		response.FailWithMessage("账号权限不足", c)
		return
	}
	req := epidemicReq.AutoNotify{}
	err := c.ShouldBind(&req)
	if err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", req))
	if err = epidemicRelatedStaffService.AutoNotify(req); err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	response.OkWithMessage("操作成功", c)
}

// Return 返岗
func (epidemicRelatedStaffApi *EpidemicRelatedStaffApi) Return(c *gin.Context) {
	req := epidemicReq.EpidemicRelatedStaffReturn{}
	err := c.ShouldBind(&req)
	if err != nil {
		global.GVA_LOG.Error("参数错误!", zap.Error(err))
		response.FailWithMessage("参数错误", c)
		return
	}
	global.GVA_LOG.Info("请求参数", zap.Any("param", req))
	if err := epidemicRelatedStaffService.Return(req); err != nil {
		global.GVA_LOG.Error("操作失败!", zap.Error(err))
		response.FailWithMessage("操作失败", c)
	} else {
		response.Ok(c)
	}
}
